
/*
*	@file	hcomm.cpp
*	@author	Artur Gilmutdinov <arturg000@gmail.com> 
*/

#include "hcomm.h"
#include "hsock.h"
#include "hcomms.h"
#include "common.h"
#define log 
//log_t::log
 
// serve remote ifs
void hcomm_t::serve_ifs(int socket)
	{
	char bf[255];
	char *s;
	char name[255];
	unsigned int size;
	int aim = -1;
//	log( "srv ifs ");
	recv(socket, name, 255, 0);
	
//	log( name);
	map<char*, skel_t*>::iterator it = obj.begin();
	//log(inttostr(obj.size()));
	// find object
	bool ok = 0;
	while (it!=obj.end())
	{
		strcpy(bf, it->first);
//		log("serching for/ current");
//		log(bf);
//		log(name);
		if (strsrav(bf, name)) { ok = 1;  break; }
		it++;
	}
	if (!ok)
	{
//		log("No such object ");
//		log(name);
		return;
	}
	
		while (1)
		{
			strcpy(bf,"");
			recv(socket, bf, 255, 0);
		//	cout << bf;
			if (!strcmp(bf,"")) continue;
			//	Stop interface serving. Client initiator.
			if (strsrav(bf, "ifs stop\n"))
			{
				close(socket);
				break;
			}
			// Call real methods.
		//	log("CALL");
		//	log(bf);
			s = it->second->call(socket, bf);	 
		}  		
	}

// serve input connections
void hcomm_t::serve(int socket, char *ip, int port)
	{
		char bf[255];
		// recv hcomm_t command
		recv(socket, bf, 255, 0);
//		log("comm:");
//		log(bf);
		if (!strcmp(bf,"ifs\n"))
			serve_ifs(socket);
		else if (strsrav(bf, "upload\n"))
			{ 
			//	Send file.
				uploadfile(socket);
				close(socket);
			}
	}
	
void hcomm_t::connect()
	{
	//	log( "Start connect\n");
		hsock_t h;
		int socket;
	//	log( "starting client\n");
		socket = h.client(srvip, srvport);
		char *bf = new char [255];
		strcpy(bf, "addnode\n");
		send(socket, bf, 255, 0);
		sprintf(bf,"%s\n", name);
		send(socket, bf, 255, 0);
		recv(socket, bf, 255, 0);
		sscanf(bf, "%d", &cliport);
		
	/*	if (cliport<1000 || cliport>65535)
			{
			cout << "Node " << name << " connecting error. " << endl;
			//close(socket);
			//return;		
			}
	*///	log(bf);
		close(socket);
		start_server();	
	}
	
// upload file
void hcomm_t::uploadfile(int socket)
{
	char bf[255];
	recv(socket, bf, 255, 0);
	if (pathsolver==NULL) 
		throw "pathsolver undefined";
	FILE *f = fopen(pathsolver->pathsolve(bf), "r");
	fseek(f, 0L, SEEK_END);
	int size = ftell(f);
	fseek(f, 0L, SEEK_SET);
	
	sprintf(bf, "%d\n", size);
	send(socket, bf, 255, 0);
	
	while (size>255*sizeof(char))
	{
		fread(bf,sizeof(char)*255, 1 , f);  
		send(socket, bf, 255, 0);
		size-=255*sizeof(char);
	}
	fread(bf,sizeof(char)*255, 1 , f);  
	send(socket, bf, 255, 0);
	fclose(f);
}

// start local server thread
void *srv_fnc(void *a)
	{
		
		hcomm_t *b = (hcomm_t*) a;
		hsock_t s;
		s.server<hcomm_t>(b, b->cliport);
	}

// start server
void hcomm_t::start_server()
	{
		
		pthread_create(&srv_th, NULL, srv_fnc, this);
//		hsock_t s;
//		s.server<hcomm_t>(this, cliport);

	}
	
void hcomm_t::join()
{
	pthread_join(srv_th, NULL);
}